/*  iImager (network disk imaging via iscsi)
	Copyright (C) 2009-2010 Yao Wei <njustyw@gmail.com>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
*/

#ifndef QLOGDB_H
#define QLOGDB_H

#include <QtCore>

class LogInsertEvent : public QObject
{
	Q_OBJECT
public:
	static LogInsertEvent* getInstance();

signals:
	/** This signal will be emitted when we add a new log into LogDB*/
	void signal_insertSucceed();
	
	/** This signal will be emitted when we have finished imaging one hard disk*/
	void signal_insertDoneTask();

private:
	static LogInsertEvent* instance;

	LogInsertEvent(QObject* parent = 0);
	~LogInsertEvent();

	friend class LogDB;
};

#define READYFOR_COPY_DISK	0
#define DOING_COPY_DISK		1
#define DONE_COPY_DISK		2
#define ERROR_COPY_DISK		3
#define PAUSE_COPY_DISK		4
#define DROP_COPY_DISK		5
#define RESUME_COPY_DISK	6

/** Log/record database */
class LogDB : public QObject
{
Q_OBJECT
public:

	enum LogDB_Error{
		UNKNOWN_ERROR,
		CONNECTION_ERROR, 
		SQL_ERROR,
		NODATA_ERROR
	};

	static LogDB* instance(const QString& database, const QString& host,
							const QString& username, const QString& password);

	static LogDB* instance();

	/** Get error type for database */
	LogDB_Error getError()const{return error;}

	/** Open and initialize logdb */
	bool initDB();

	bool isConnected()const;

	/** Close logDB */
	void closeDB();

	/** Add one record of start program*/
	bool addSystemOnLog();

	/** Add one record of quit program*/
	bool addSystemOffLog();

	/** Add one record of config program*/
	bool addSystemConfigLog(const QString& msg, int type = 0);

	/** 
	 Add one record of new disk coming out
	 @param _product the hard disk's product ID
	 @param _vendor the hard disk's vendor ID
	 @param _sn the hard disk's serial number
	 @param capcity the hard disk's total size
	 @param rackIndex the rack index that the hard disk locates in
	 @param slotIndex the slot index that the hard disk locates in
	 @param hdId the index for database hdinfo
	 @param hdlocId the index for database  hdloc
	 @return false on failure, true otherwise
	 */
	bool addDiskFoundLog(const QString& _product, const QString& _vendor, const QString& _sn, 
						   quint64 capcity, int rackIndex, int slotIndex, 
						   int& hdId, int& hdlocId);

	/** 
	 Add user information for login uForensicConsole and iImager
	 @param username the userid for login uForensicConsole and iImager
	 @param password the password for login uForensicConsole and iImager
	 @param userType the access type for login uForensicConsole and iImager
	 @return false on failure, true otherwise
	 */
	bool addUserInfo(const QString& username, const QString& password, int userType);

	/** 
	 Verify user and password. 
	 @param user The user ID
	 @param password The password of user ID that has been crypted by md5
	 @param type The access type of user 
	 @return false on user doesn't match password, otherwise true. 
	*/
	bool verifyUserPassword(const QString& user, const QString& crypPassword, int& type);


	/** 
	 Add one record of preparing imaging one hard disk 
	 @param hdId, hdlocId the index for database hdinfo and hdloc
	 @param imagingName the imaging output name that will be wrote to
	 @param imagingFormat the imaging file format (We support DD and E01)
	 @param hashType the imaging hash type (We support any combination of md5, sha1 and sha256)
	 @param caseNo the case number that the hard disk
	 @param the index of this log message
	 @return false on failure, true otherwise
	*/
	bool addDiskReadyForCopyLog(int hdId, int hdlocId, const QString& imgingName, 
								int imagingFormat, int hashType, const QString& caseNo, int& rId);

	/** Add one record of starting imaging one hard disk */
	bool addDiskStartCopyLog(int hdId, int hdlocId, int rId);

	/** Add one record of finishing imaging one hard disk */
	bool addDiskDoneCopyLog(int hdId, int hdlocId, int rId, double meanSpeed, int totalTime);

	/** Add one record of droping imaging one hard disk */
	bool addDiskDropCopyLog(int hdId, int hdlocId, int rId);

	/** Add one record of exception */
	bool addExceptionCopyLog(int hdId, int hdlocId, const QString& msg, int rId);

	/** Add one record of hard disk being plugged out*/
	bool addDiskRemoveLog(int hdId, int hdlocId);

	/** Mark the status RUNNING*/
	bool startRunning(int rId);

	/** Mark the status DONE*/
	bool doneRunning(int rId);

	/** Mark the status DROP*/
	bool dropRunning(int rId);


	/** 
	 Select log message from database
	 @param pageCount the count of message that will be retrieved
	 @param starOffset the offset in the log database
	 @param msgs the message that will return
	 @return false on failure, true otherwise
    */
	bool selectLogMsg(int pageCount, int startOffset, QList<QString>& msgs);

	/** Get the message count of logDB*/
	int  getMsgCount();

	/** 
	 Retrieve the undone task from LogDB
	 @param imagingOutputNames the list of imaging files
	 @param imagingTypes the list of imaging types
	 @param hashTypes the list of  hash types
	 @param caseNos the list of case numbers
	 @param vendorIds the list of hard disk's vendor ID 
	 @param productIds the list of hard disk's product ID
	 @param SNs the list of case numbers
	 @param mediaSizes the list of hard disk's capcity
	 @return the count of undone task
	*/
	int  getUndoneTasks(QList<QString>& imagingOutputNames, QList<int>& imagingTypes, 
						QList<int>& hashTypes, QList<QString>& caseNos,
						QList<QString>& vendorIds, QList<QString>& productIds,  
						QList<QString>& SNs, QList<quint64>& mediaSizes);

	int removeAllUndoneTasks();

	/** 
	 Retrieve the case numbers from LogDB
	 @param caseNos the list of case numbers
	 @return the count of case numbers
	*/
	int getAllCaseNos(QList<QString>& caseNos);

	/** 
	 Retrieve the imaging file list has been finished from LogDB
	 @param imagingOutputNames the list of imaging files
	 @param imagingTypes the list of imaging types
	 @param mediaSizes the list of imaging file's capcity
	 @param hashTypes the list of  hash types
	 @param caseNos the list of case numbers
	 @param julianDays the list of starting time of mirroring hard disk 
	 @param maxRId the max id of these records in the log
	 @return the number of list
	*/
	int getAllDoneList(QList<QString>& imagingOutputNames, QList<int>& imagingTypes, 
					QList<quint64>& mediaSizes, QList<int>& hashTypes, 
					QList<QString>& caseNos, QList<int>& julianDays, int& maxRId);


	/** 
	 Retrieve the imaging file list from LogDB
	 @param caseNo the search filter
	 @param imagingOutputNames the list of imaging files
	 @param imagingTypes the list of imaging types
	 @param mediaSizes the list of imaging file's capcity
	 @param hashTypes the list of  hash types
	 @param caseNos the list of case number
	 @return the number of list
	*/
	int getAllDoneListByCaseNo(const QString& caseNo, QList<QString>& imagingOutputNames, QList<int>& imagingTypes, 
					QList<quint64>& mediaSizes, QList<int>& hashTypes, QList<QString>& caseNos);


private:
	LogDB(QObject* parent = 0);

	static LogDB* pInstance;
	LogDB_Error error;
};

#endif
